package live.cz.dao;

import java.io.ByteArrayInputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import live.api.impl.MobileReqRes;
import live.common.DBHelper;
import live.common.ErrorException;
import live.common.ErrorMeg;
import live.common.Format;
import live.common.Log4jXmlConfig;
import live.common.Page;
import live.common.PostParam;
import live.common.Verifystring;
import live.cz.entity.Order;
import live.cz.response.XmlFormart;
import live.response.WebServicePay;


import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class OrderRecharge {
	private boolean fillFlag;
	private String errorCode;
	private StringBuffer sql = null;
	private Format format = Format.getInstance();
	private MobileReqRes mrq = null;
	Map<String, String> orderParams = null;
	private Order item = null;
	private Logger log = Log4jXmlConfig.getInstance().returnLogger(
			OrderRecharge.class);

	public String getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(String errorCode) {
		this.errorCode = errorCode;
	}

	public static void main(String[] args) {
		String verifyString = null;
		Order order = new Order();
		order.setOrderid("20120103151336669");
		order.setPhonenum("15972275058");
		order.setProdid("8113");
		Map<String, String> orderParams = new OrderRecharge().returnPublicMap(order, "1");
		verifyString = new Verifystring().returnVerifystring(orderParams);
		orderParams.put("verifystring", DigestUtils.md5Hex(verifyString));
		String result = new WebServicePay().returnResult(
				PostParam.PRE_SEARCH, orderParams);
		System.out.println(result);
	}
	
	/**
	 * 预查询提交订单
	 * 
	 * @param order
	 * @return
	 * @throws SQLException
	 * @throws ErrorException
	 */
	public Order returnResult(Order order) throws ErrorException {
		boolean flag = false;
		String verifyString = null;
		orderParams = returnPublicMap(order, "1");
		verifyString = new Verifystring().returnVerifystring(orderParams);
		orderParams.put("verifystring", DigestUtils.md5Hex(verifyString));
		try {
			// 添加提交服务请求信息command=1
			mrq = new MobileReqRes(); 
			mrq.insertSendRequest(PostParam.PRE_SEARCH, orderParams);
			String result = new WebServicePay().returnResult(
					PostParam.PRE_SEARCH, orderParams);
			Document doc = new XmlFormart().xmlToDocument(result.trim());
			addResponse(doc, PostParam.PRE_SEARCH.toString(), "jit");
			item = returnResultInfos(doc, order.getPhonenum());
			if (result.indexOf("<") != -1) {
				if (item.getResultno() == 0 || item.getResultno()==1011) {
					item.setSalePrice(order.getSalePrice());
					item.setProPrice(order.getProPrice());
					item.setMemberNo(order.getMemberNo());
					item.setUserIdent(order.getUserIdent());
					item.setProdInfo(order.getProdInfo());
					// 成功
					setErrorCode("10001");
					item.setLastState(0);
				} else {
					int errorNo = item.getResultno();
					item.setLastState(4);
					// 失败
					setErrorCode("10004");
					throw new ErrorException(ErrorMeg.returnError(errorNo));
				}
				updateOrderLastState(item);
			} else {
				// 失败
				setErrorCode("10004");
				throw new ErrorException(result);
			}
		} catch (ErrorException e) {
			String resultno = directSearch(order.getOrderid());
			// 订单失败
			if (resultno.equals("1009") || resultno.equals("4")) {
				setErrorCode("10004");
			} else {
				// 成功
				setErrorCode("10001");
			}
			throw new ErrorException(e.getMessage());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			setErrorCode("10003");
			log.info(item.getOrderid() + "手机充值订单提交接口出现异常!");
			e.printStackTrace();
		}
		return item;
	}
	
	

	/**
	 * 充值预查询
	 * 
	 * @param order
	 * @return
	 * @throws ErrorException
	 */
	public Order searchFill(Order order) throws ErrorException {
		String verifyString = null;
		orderParams = returnPublicMap(order, "2");
		verifyString = new Verifystring().returnVerifystring(orderParams);
		orderParams.put("verifystring", DigestUtils.md5Hex(verifyString));
		try {
			// 添加预查询服务请求信息command=2
			mrq = new MobileReqRes(); 
			mrq.insertSendRequest(PostParam.PRE_SEARCH.toString(),
					orderParams);
			String result = new WebServicePay().returnResult(
					PostParam.PRE_SEARCH, orderParams);
			Document doc = new XmlFormart().xmlToDocument(result.trim());
			addResponse(doc, PostParam.PRE_SEARCH.toString(), "jit");
			int resultno = Integer.valueOf(doc.selectSingleNode(
					"//items/item[@name='resultno']/./@value").getText());
			if (resultno != 0) {
				this.setFillFlag(false);
				throw new ErrorException(ErrorMeg.returnError(resultno));
			} else {
				this.setFillFlag(true);
				order.setTranid(doc.selectSingleNode(
						"//items/item[@name='tranid']/./@value").getText());
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			throw new ErrorException(e.getMessage());
		} catch (ErrorException e) {
			// TODO: handle exception
			throw new ErrorException(e.getMessage());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			throw new ErrorException(e.getMessage());
		}
		return order;
	}

	/**
	 * 添加即时通知结果
	 * 
	 * @param doc
	 * @param service
	 * @param rt
	 */
	public void addResponse(Document doc, String service, String rt) {
		Map map = new HashMap();
		Element root = doc.getRootElement().element("items");
		Element node = null;
		for (Iterator i = root.elementIterator(); i.hasNext();) {
			node = (Element) i.next();
			map.put(node.attributeValue("name"), node.attributeValue("value"));
		}
		mrq = new MobileReqRes(); 
		mrq.insertSendRespnse(service, rt, map);
	}

	/**
	 * Map共用封装
	 * 
	 * @param order
	 * @param command
	 * @return
	 */
	private Map returnPublicMap(Order order, String command) {
		orderParams = new LinkedHashMap<String, String>();
		orderParams.clear();
		orderParams.put("prodid", order.getProdid());
		orderParams.put("agentid", PostParam.AGENTID);
		orderParams.put("backurl", "");
		orderParams.put("returntype", "2");
		orderParams.put("orderid", order.getOrderid());
		orderParams.put("mobilenum", order.getPhonenum());
		orderParams.put("source", PostParam.SOURCE.toString());
		orderParams.put("command", command);
		orderParams.put("mark", "");
		return orderParams;
	}

	/**
	 * 订单查询，对账处理
	 * 
	 * @param orderId
	 * @return
	 */
	private String directSearch(String orderId) {
		String resultno = null;
		orderParams = new LinkedHashMap<String, String>();
		orderParams.clear();
		orderParams.put("agentid", PostParam.AGENTID);
		orderParams.put("backurl", "");
		orderParams.put("returntype", "2");
		orderParams.put("orderid", orderId);
		orderParams.put("source", PostParam.SOURCE.toString());
		String verifyString = new Verifystring()
				.returnVerifystring(orderParams);
		orderParams.put("verifystring", DigestUtils.md5Hex(verifyString));
		String result = null;
		try {
			result = new WebServicePay().returnResult(PostParam.DIRECT_SEARCH
					.toString(), orderParams);
			if (format.isNotNullOrEmpty(result)) {
				resultno = returnNodeValue(result);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 返回充值状态resultno
	 * 
	 * @param str
	 * @return
	 */
	private String returnNodeValue(String str) {
		String resultno = null;
		try {
			Document doc = new SAXReader().read(new ByteArrayInputStream(str
					.getBytes()));
			Element root = doc.getRootElement().element("items");
			Element node = null;
			for (Iterator i = root.elementIterator(); i.hasNext();) {
				node = (Element) i.next();
				if (node.attributeValue("name").equals("resultno")) {
					resultno = node.attributeValue("value");
				}
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return resultno;
	}

	/**
	 * 封装返回的订单信息
	 * 
	 * @param doc
	 * @param phonenum
	 * @return
	 */
	private Order returnResultInfos(Document doc, String phonenum) {
		Element e = (Element) doc.selectSingleNode("//items");
		try {
			item = new Order();
			item.setProdid(XmlFormart.returnXmlNodeValue(e, "item", "prodid"));
			item
					.setOrderid(XmlFormart.returnXmlNodeValue(e, "item",
							"orderid"));
			item.setResultno(Integer.parseInt(XmlFormart.returnXmlNodeValue(e,
					"item", "resultno")));
			item.setTranid(XmlFormart.returnXmlNodeValue(e, "item", "tranid"));
			item.setPhonenum(phonenum);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			log.info("充值订单数据封装出现异常!");
			log.error(e1.getMessage());
			item = null;
		}
		return item;
	}

	/**
	 * 新增充值记录
	 * 
	 * @param item
	 * @throws SQLException
	 */
	public int insertServer(Order item) throws SQLException {
		int count = 0;
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer(
				"INSERT INTO Mobile_Record (orderId,phonenum,dateTime,prodid,proPrice,salePrice,userIdent,memberNo,laststate,prodInfo,file1,tranid,resultNo) Values(")
				.append("'").append(item.getOrderid()).append("',").append("'")
				.append(item.getPhonenum()).append("',").append("'").append(
						format.dateFormatString(new Date(),
								"yyyy-MM-dd HH:mm:ss")).append("','").append(
						item.getProdid()).append("',").append("'").append(
						item.getProPrice()).append("',").append("'").append(
						item.getSalePrice()).append("',");
		if (item.getUserIdent() != null) {
			sql.append("'" + item.getUserIdent() + "'");
		} else {
			sql.append("NULL");
		}
		sql.append(",");
		if (item.getMemberNo() != null) {
			sql.append("'" + item.getMemberNo() + "'");
		} else {
			sql.append("NULL");
		}
		sql.append(",");
		sql.append(5).append(",'").append(item.getProdInfo()).append("','")
				.append("on").append("','").append(item.getTranid()).append(
						"',0)");
		count = dh.update(sql.toString());
		dh.close();
		return count;
	}
	
	/**
	 * 同一个用户，10S内不能对同一个手机号进行重复充值
	 * @return
	 */
	public boolean searchOrderBy(String memberNo,String phoneNum){
		boolean flag = true;
		DBHelper dh = DBHelper.getInstance();
		try {
			String procStr = "{call valRecordState(?,?)}"; 
			Object[] args = new Object[2];
			args[0] = memberNo;
			args[1] = phoneNum;
			Order item =  (Order)dh.query(procStr,args);
			if(format.isNotNullOrEmpty(item)){
				flag = false;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
//			dh.close();
		}
		return flag;
	}

	/**
	 * 更改订单信息
	 * 
	 * @param item
	 * @throws SQLException
	 */
	public void updateOrder(Order item) throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("UPDATE Mobile_Record SET realPrice=").append(
				item.getRealPrice()).append(",").append("tranid='").append(
				item.getTranid()).append("',").append("resultNo='").append(
				item.getResultno()).append("'").append(" where orderId='")
				.append(item.getOrderid()).append("'");
		dh.update(sql.toString());
		dh.close();
	}

	public void updateRecordOrder(Order item) throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("UPDATE Mobile_Record SET realPrice=").append(
				item.getRealPrice()).append(",").append("laststate=").append(
				item.getLastState()).append(",notice_time='").append(
				format.dateFormatString(item.getNoticeTime(),
						"yyyy-MM-dd HH:mm:ss")).append("'").append(",").append(
				"resultNo='").append(item.getResultno()).append("'").append(
				" where orderId='").append(item.getOrderid()).append("'");
		dh.update(sql.toString());
		dh.close();
	}

	/**
	 * 修改订单最终状态
	 * 
	 * @param item
	 * @throws SQLException
	 */
	public void updateOrderLastState(Order item) throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("UPDATE Mobile_Record SET laststate=").append(
				item.getLastState()).append(" where orderId='").append(
				item.getOrderid()).append("'");
		dh.update(sql.toString());
		dh.close();
	}

	public void updateOrderResponse(Order item) throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("UPDATE Mobile_Record SET laststate=").append(
				item.getLastState()).append(",").append("resultNo='").append(
				item.getResultno()).append("' where orderId='").append(
				item.getOrderid()).append("'");
		dh.update(sql.toString());
		dh.close();
	}

	/***************************************************************************
	 * 根据memberNo 查询充值信息
	 * 
	 * @param memberNo
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public List<Order> list_Mobile(String memberNo) throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("SELECT * FROM Mobile_Record WITH(NOLOCK) WHERE 1=1 ");
		sql.append(" order by dateTime desc ");
		Order item = null;
		List results = new ArrayList();
		dh.setBeanClass(Order.class);
		List orderList = dh.queryRecords(sql.toString());
//		dh.close();
		return results;
	}

	/**
	 * 单个订单查询
	 * 
	 * @param orderId
	 * @return
	 */
	public Order getOrderInfo(String orderId) {
		DBHelper dh = DBHelper.getInstance();
		sql = new StringBuffer("SELECT * FROM Mobile_Record WITH(NOLOCK) WHERE orderId='"
				+ orderId + "'");
		dh.setBeanClass(Order.class);
		Order item = null;
		try {
			item = (Order) dh.query(sql.toString());
//			dh.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			return item;
		}
	}

	/***************************************************************************
	 * 根据memberNo查询充值信息 分页
	 * 
	 * @param memberNo
	 * @return
	 * @throws SQLException
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<Order> list_Mobile_fy(String memberNo, Order order, Page page)
			throws SQLException {
		DBHelper dh = DBHelper.getInstance();
		String execSql = "{call pro_Common_PageView(?,?,?,?)}";
		sql = new StringBuffer(
				"SELECT *  FROM Mobile_Record WITH(NOLOCK) WHERE 1=1 AND memberNo=").append(
				"'").append(memberNo).append("'");
		if (format.isNotNullOrEmpty(order.getStartDate())) {
			sql.append(" and dateTime>'").append(order.getStartDate()).append(
					"'");
		}
		if (format.isNotNullOrEmpty(order.getEndDate())) {
			sql.append(" and dateTime<'").append(
					format.getInstance().returnNextDate(order.getEndDate()))
					.append("'");
		}
		if (order.getLastState() != -9) {
			sql.append(" and lastState=").append(order.getLastState());
		}
		sql.append(" order by dateTime desc");
		Object[] args = new Object[4];
		args[0] = sql.toString();
		args[1] = page.getPageIndex();
		args[2] = page.getPageSize();
		args[3] = "";
		Order item = null;
		dh.setBeanClass(Order.class);
		List results = dh.queryRecords(execSql, args);
		page.setRecordCount(dh.returnOutParam(execSql, args));
//		dh.close();
		return results;
	}

	public boolean isFillFlag() {
		return fillFlag;
	}

	public void setFillFlag(boolean fillFlag) {
		this.fillFlag = fillFlag;
	}
}
